import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_acrylic/flutter_acrylic.dart';
import 'package:win32/win32.dart';
import 'package:win32_registry/win32_registry.dart';
import 'package:path_provider/path_provider.dart';

enum InterfaceBrightness {
  light,
  dark,
  auto,
}

extension InterfaceBrightnessExtension on InterfaceBrightness {
  bool getIsDark(BuildContext? context) {
    if (this == InterfaceBrightness.light) return false;
    if (this == InterfaceBrightness.auto) {
      if (context == null) return true;

      return MediaQuery.of(context).platformBrightness == Brightness.dark;
    }

    return true;
  }

  Color getForegroundColor(BuildContext? context) {
    return getIsDark(context) ? Colors.white : Colors.black;
  }
}

Future<void> showAcrylic(Color color) async {
  InterfaceBrightness brightness =
      Platform.isMacOS ? InterfaceBrightness.auto : InterfaceBrightness.dark;
  int? buildNumber = getWindowBuildNumber();
  WindowEffect effect;
  if (buildNumber! >= 1803) {
    effect = WindowEffect.acrylic;
  } else {
    effect = WindowEffect.aero;
  }
  if (kDebugMode) {
    print("effect:$effect");
  }
  await Window.setEffect(
      effect: effect,
      color: color,
      dark: brightness == InterfaceBrightness.dark);
  if (Platform.isMacOS) {
    if (brightness != InterfaceBrightness.auto) {
      Window.overrideMacOSBrightness(
        dark: brightness == InterfaceBrightness.dark,
      );
    }
  }
}

int? getWindowBuildNumber() {
  const regCurrentVersionKey = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion';
  final key =
      Registry.openPath(RegistryHive.localMachine, path: regCurrentVersionKey,desiredAccessRights: AccessRights.readOnly);
  final mCurrentVersion = key.getValueAsString('CurrentVersion');
  if (kDebugMode) {
    print("mCurrentVersion:$mCurrentVersion");
  }
  final mUBR = key.getValueAsInt('UBR');
  if (kDebugMode) {
    print("mUBR:$mUBR");
  }
  // updateRegistryTest();
  return mUBR;
}


Future<void> updateRegistryTest(bool isAutoStart) async {
  const regCurrentVersionKey = r'Software\Microsoft\Windows\CurrentVersion\Run';
  final key =
  Registry.openPath(RegistryHive.currentUser, path: regCurrentVersionKey,desiredAccessRights: AccessRights.writeOnly);
  key.createKey("WeChat");
  // GetModuleFileNameEx()
  // Pointer<Utf16>? path ;
  // var result = GetModuleFileName(NULL, path, MAX_PATH);
  Directory appDir = await getApplicationDocumentsDirectory();
  String appDirPath = appDir.path;
  // print("result:$result");
  // print("result:$result");
  print("path:$appDirPath");
  key.createValue(const RegistryValue("WeChat", RegistryValueType.string, "D:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe"));
  key.close();
}

Future<void> closeAcrylic() async {
  await Window.setEffect(effect: WindowEffect.disabled);
}

class WindowUtil {
  WindowUtil._internal();

  factory WindowUtil() => _instance;

  static late final WindowUtil _instance = WindowUtil._internal();

  // double titleBarHeight;
  // double borderSize;
  // double scaleFactor;
  // int dpi;

  Size get titleBarButtonSize {
    double height = titleBarHeight - borderSize;
    double scaleFactor = this.scaleFactor;
    double cyCaption = systemMetric(SM_CYCAPTION);
    cyCaption /= scaleFactor;
    double width = cyCaption * 2;
    if (kDebugMode) {
      print("titleBarButtonSize:${Size(width, height)}");
    }
    return Size(width, height);
  }

  double get titleBarHeight {
    int dpiToUse = dpi;
    double cyCaption = systemMetric(SM_CYCAPTION, dpiToUse: dpiToUse);
    cyCaption = (cyCaption / scaleFactor);
    double cySizeFrame = systemMetric(SM_CYSIZEFRAME, dpiToUse: dpiToUse);
    cySizeFrame = (cySizeFrame / scaleFactor);
    double cxPaddedBorder = systemMetric(SM_CXPADDEDBORDER, dpiToUse: dpiToUse);
    cxPaddedBorder = (cxPaddedBorder / scaleFactor).ceilToDouble();
    double result = cySizeFrame + cyCaption + cxPaddedBorder;
    if (kDebugMode) {
      print("titleBarHeight:$result");
    }
    return result;
  }

  double get scaleFactor {
    double result = this.dpi / 96.0;
    return result;
  }

  int get dpi {
    return GetDpiForSystem();
  }

  double get borderSize {
    return systemMetric(SM_CXBORDER);
  }

  double systemMetric(int metric, {int dpiToUse = 0}) {
    var result = GetSystemMetrics(metric).toDouble();
    return result;
  }
}
